<?php
	header('Content-Type:text/html;charset=utf-8');
	class Model{
		//表名
		private $table;
		//SQL语句
		private $options = array();
		//link保存mysqli的对象
		private static $link=null;
		//保存sql语句
		private $sql;


		
		/**
		 * 构造方法时传入一个表名表示对这张表进行操作
		 * @param string $table
		 */
		public function __construct($table){
			//保存表名 
			//先判断一下link成员属性是事存在 如果不存在再实例化他如果存在就不实例化mysqli
			if(is_null(self::$link)){
				$link = new Mysqli(C('DB_HOST'),C('DB_USER'),C('DB_PWD'),C('DB_NAME'));
				$link->query('SET NAMES '.C('DB_CHARSET'));
				//判断如果出现错误 的话那么就die显示错误 信息
				if($link->connect_errno){
					die($link->connect_error);
				}
				//如果没有出现错误 那么就将这个$link对象保存到成员属性中
				self::$link = $link;
				
			}	
				//判断是否存在表前缀
				if(C('IS_TABLE_PREFIX')){
					//添加表前缀
					$table = C('TABLE_PREFIX').$table;
				}
				$this->table = $table;
				$this->options();
		}
		
		/**
		 * 设置要查询的 表名 
		 * @param string $table
		 * @return Model
		 */
		public function table($table){
			$this->table = $table;
			return $this;
		}

		
		/**
		 * 返回执行的sql语句
		 */
		public function getsql(){
			echo '<h2>'.$this->sql.'</h2>';
		}
		
		
		
		/**
		 * 返回结果集的查询方法
		 */
		public function query($sql=null){
			if(is_null($sql)){
				$this->sql = "SELECT ".$this->options['field']." FROM ".
						$this->table.$this->options['join'].$this->options['where'].
						$this->options['group'].$this->options['having'].$this->options['order'].$this->options['limit'];
			}else{
				$this->sql = $sql;
			}
			
			
// 			echo $this->sql.'<br />';die;
			return $this->_query();
		}
		
		
		/**
		 * model内容使用的查询方法返回结果集
		 */
		private function _query(){
			$result = self::$link->query($this->sql);
			//如果存在错误 那么就die
			if(self::$link->errno){
				die('<h2 style="color:red">'.self::$link->error.'</h2><h3>语句:'.$this->sql.'</h3>');
			}
			//不存在错误那么就将结果集返回来
			$rows = array();
			while($row = $result->fetch_assoc()){
				$rows[] = $row;
			}
			//释放资源
			$result->free();
//			self::$link->close();
			return $rows;
		}
		
		
		/**
		 * 初始化条件
		 */
		private function options(){
			$this->options = array(
					'field'=>'*',
					'join'=>'',
					'where'=>'',
					'group'=>'',
					'having'=>'',
					'order'=>'',
					'limit'=>''
			);
		}
		
		
		/**
		 * 指定查询的字段
		 * @param string $fields
		 * @return Model
		 */
		public function field($fields=null){
			//如果传入了字段名那么就以用户传入的为准 如果没有没传入那么就以Model的为准 也就是*
			$this->options['field'] = is_null($fields)?$this->options['field']:$fields;
			return $this;	
		}
		
		/**
		 * 将一个数组转为
		 * 处理了如果传入的是一个array('id<=',19) 那么处理出来的字符串就是
		 * id<=19  如果不存在那么就是等于符号 
		 */
		private function convertString($arr,$str=null){
			if(is_array($arr)){
				$tmp = '';
				$fields = array_keys($arr);
				$vals = array_values($arr);
				$pattern = "/([<=|<|>|>=|<>])/";
				foreach($fields as $k=>$v){
					preg_match($pattern, $v,$fh);
					if(!empty($fh)){
						$v = rtrim($v,$fh[0]);
						$tmp .= $v.$fh[0]."'".$vals[$k]."'".' '.$str;
					}else{
						$tmp .= $v.'='."'".$vals[$k]."'".' '.$str;
					}
				}
				return $tmp;
			}else{
				die('请传入一个数组');
			}
		}
		
		/**
		 * 传入一个字符串任意组合条件语句，
		 * 传入一个数组那么表示AND关系
		 * 传入两个数组表示OR 关系
		 * @param string $where
		 * @return Model
		 */
		public function where($where=null,$where2=null){
			$tmp = '';
			//如果传入是一个数组那么将他转为 key=val AND key=val
			if(is_array($where)){
				$tmp = rtrim($this->convertString($where,' AND '),' AND ');
			}
			
			//如果where为一个字符串那么就直接连接他
			if(is_string($where)){
				$tmp = $where;
			}
		
			//如果传入两个数组或两个字符串那么表示为一个OR表达式
			if(is_array($where) && is_array($where2)){
				$where1 = $this->convertString($where);
				$where2 =  $this->convertString($where2);
				$tmp = $where1 .' OR '.$where2;
			}				
					
			$this->options['where'] = ' WHERE '.$tmp;
			return $this;			
		}
		
		/**
		 * 只查询一条数据
		 */
		public function find(){
			$this->options['limit'] = ' LIMIT 1 ';
			$row = $this->query();
			return current($row);
		}
		
		/**
		 * 按什么字段进行分组
		 * @param string $group
		 */
		public function group($group=null){
			$group = is_null($group)?$this->options['group']:$group;
			$this->options['group'] = ' GROUP BY '.$group.' ';
			return $this;
		}
		
		/**
		 * group by后面的having子句
		 * @param string $having
		 */
		public function having($having=null,$having2=null){
// 			$having = is_null($having)?$this->options['having']:$having;
// 			$this->options['having'] = ' HAVING '.$having;
// 			return $this;
			$tmp = '';
			//如果传入是一个数组那么将他转为 key=val AND key=val
			if(is_array($having)){
				$tmp = rtrim($this->convertString($having,' AND '),' AND ');
			}
				
			//如果where为一个字符串那么就直接连接他
			if(is_string($having)){
				$tmp = $having;
			}
			
			//如果传入两个数组或两个字符串那么表示为一个OR表达式
			if(is_array($having) && is_array($having2)){
				$having1 = $this->convertString($having);
				$having2 =  $this->convertString($having2);
				$tmp = $having1 .' OR '.$having2;
			}
			$this->options['having'] = ' HAVING '.$tmp;
			return $this;
		}
		
		/**
		 * order by  排序
		 * @param string $order
		 */
		public function order($order=null){
			$order = is_null($order)?$this->options['order']:$order;
			$this->options['order'] = ' ORDER BY '.$order;
			return $this;
		}
		
		/**
		 * 限制显示条数
		 * @param string $limit
		 */
		public function limit($limit=null,$limit2=null){
			if(is_int($limit)){
				if(is_null($limit2)){
					$this->options['limit'] = ' LIMIT '.$limit;
				}else{
					$this->options['limit'] = ' LIMIT '.$limit.','.$limit2;
				}
			}
			return $this;
		}
		
		/**
		 * 返回当前表所有数据
		 */
		public function all(){
			return $this->query();
		}
		
// 		/**、
// 		 *  执行没有结果集的sql语句 返回受影响行数
// 		 */
// 		public function exec($sql=null){
			
// 		}
		
		/**
		 * 执行没有返回结果集的sql 语句
		 * DELETE UPDATE INSERT 只返回受影响 行数的结果
		 * @return int
		 */
		public function _exec($sql=null){
			if(!is_null($sql)){
				$this->sql = $sql;
			}
			self::$link->query($this->sql);
			if(self::$link->errno){
				die('<h2 style="color:red">'.self::$link->error.'</h2><h3>语句:'.$this->sql.'</h3>');
			}
			return self::$link->affected_rows;
			
		}
		
		/**
		 * 将值转为相应的整有引号的字符串
		 * @param Array $data
		 * @return String、、、、、、、、、、、、、、、、、、
		 */
		private function valueAddQuote($data){
			if(!is_array($data)) die('必须传入一个数组');
			$str = "'".implode("','",$data)."'";
			return $str;
		}
		
		
		
		/**
		 * 插入数据
		 * 如果传入的是field=val1,field=val2  将他整合为 
		 * 					  INSERT INTO table(field,field2) VALUES(val1,val2)
		 * 如果传入的是一个数组 那么将他直接转为 INSERT INTO table(field,field2) VALUES(val1,val2)
		 * @param string $data
		 * @return int 
		 */
		public function add($data=null){
			if(is_string($data)){
				$pattern = '[,|=]';
				$arr = preg_split($pattern, $data);
				$newArr = array();
				for($i=0,$c=count($arr);$i<$c;$i++){
					if($i%2==0){
						$newArr[$arr[$i]] = htmlspecialchars($arr[$i+1]);
					}
				}				
				$values = $this->valueAddQuote(array_values($newArr));
				$this->options['field'] = implode(',',array_keys($newArr)); 							
			}
			if(is_array($data)){
				$values = $this->valueAddQuote(array_map('htmlspecialchars',array_values($data)));
				
				$this->options['field'] = implode(',',array_map('htmlspecialchars',array_keys($data)));
			}
			//组合SQL
			$this->sql = "INSERT INTO ".$this->table.'('.$this->options['field'].') VALUES('.$values.')';
// 			echo $this->sql;die;
			return $this->_exec();
		}
		
		/**
		 * 删除指定条件的数据
		 * @param string $data1
		 * @param string $data2
		 * @return number
		 */
		public function del($data1=null,$data2=null){
			
			//如果只有一个删除条件那么直接将他传给where函数
			if(!is_null($data1)){
				$this->where($data1);
			}
			//如果有两个删除条件那么也将他传递给 where函数
			if(!is_null($data1) && !is_null($data2)){
				$this->where($data1,$data2);
			}
			if(!$this->options['where']){
				die('必须要有删除条件');
			}
			$this->sql = "DELETE FROM ".$this->table.$this->options['where'];
			return $this->_exec();			
		}
		
		
		/**
		 * 修改指定条件的数据 如果只传入一个数组那么表示
		 * 前面一定要有where()函数 修改where中的指定条件 的内容
		 * 如果传入$data1一个数组 $data2 一个数组那么将$data1转为一个where()
		 * $data2是更新数据 
		 * @param unknown $data1
		 * @param unknown $data2
		 * 
		 */
		public function update ($data1=null,$data2=null){
			$newValue ='';
			//当传入两个数组时直接提交 
			if(is_array($data1) && is_array($data2)){
				$this->where($data1);
				$newValue .= $this->convertString($data2);
				$this->sql = "UPDATE ".$this->table." SET ".$newValue.$this->options['where'];
				return $this->_exec();
			}
			
			if(is_array($data1)){
				$newValue .= rtrim($this->convertString($data1,','),',');
			}
			if(is_string($data1)){
				$newValue .= $data1;
			}
			if(!$this->options['where']){
				die('更新数据必须要有条件');		
			}
			
			$this->sql = "UPDATE ".$this->table." SET ".$newValue.$this->options['where'];
			return $this->_exec();
			
		}
			
		
		/**
		 * join表连接   默认情况下使用LEFT JOIN
		 * 如果要使用其他连接那么 
		 */
		public function join($join=null){
			$join = is_null($join)?$this->options['join']:$join;
// 			INNER JOIN LEFT JOIN RIGHT JOIN
			$this->options['join'] .= ' LEFT JOIN '.$join;
			return $this;
		}
		
		/**
		 * 返回插入语句 的IDk与
		 */
		 public function getinsertid(){
		 	return self::$link->insert_id;
		 }
		

	}
	
	
	
// 	$mode = new Model('student');
// 	$row = $mode->find();
// 	var_dump($row);
	
// 	$affected = $mode->add(array("username"=>'asdfasdf','password'=>md5('asdfijasdif'),'email'=>'abcd@qq.com','regtime'=>time()));
// 	if($affected>0){
// 		echo '添加成功';
// 	}else{
// 		echo '添加失败';
// 	}
	
// 	$row = $mode->field('id,username,count(m.lid) as count')
// 						  ->join("midd AS m ON m.sid = s.id")
// 						  ->group('username')
// 						  ->having(array("count>"=>1,'username'=>'黄信强'))->query();
// 	var_dump($row);
	